package com.besmart.workflow.core.service.factory.extractor;

import java.util.Iterator;
import java.util.List;

import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.besmart.workflow.core.exception.ConditionExtractException;
import com.besmart.workflow.core.exception.OperationNodeExtractException;
import com.besmart.workflow.core.model.ConditionNode;
import com.besmart.workflow.core.model.Constants;
import com.besmart.workflow.core.model.OperationDescriptor;
import com.besmart.workflow.core.model.OperationNode;
@Service
public class OperationNodeExtractor {

	private static final String INCORRECT_NODE_NAME_MESSAGE = "Invalid element name in the xml file, please make sure the node name is: operation";
	@Autowired
	private ConditionExtractor conditionExtractor;

	public OperationNode extract(Element operationNode)
			throws OperationNodeExtractException, ConditionExtractException {
		if (operationNode.getName().equals(Constants.OPERATION_NAME)) {
			OperationNode node = buildOperationNodeBasicContent(operationNode);
			List<?> conditions = operationNode
					.selectNodes(Constants.CONDITION_NAME);
			Iterator<?> iter = conditions.iterator();
			while (iter.hasNext()) {
				Element conditionNode = (Element) iter.next();
				ConditionNode condition = conditionExtractor.extract(conditionNode);
				node.addCondition(condition);
			}
			return node;
		} else {
			throw new OperationNodeExtractException(
					INCORRECT_NODE_NAME_MESSAGE);
		}
	}

	private OperationNode buildOperationNodeBasicContent(Element operationNode) {
		OperationDescriptor descriptor = extractOperationDescriptor(operationNode);
		OperationNode node = new OperationNode(descriptor);
		String input = operationNode.attributeValue(Constants.OPERATION_INPUT);
		String template = operationNode.attributeValue(Constants.OPEARTION_TEMPLATE);
		node.setInput(input);
		node.setTemplate(template);
		return node;
	}

	private OperationDescriptor extractOperationDescriptor(Element operationNode) {
		String id = operationNode.attributeValue(Constants.OPERATION_ID);
		String application = operationNode
				.attributeValue(Constants.OPERATION_APPLICATION);
		String type = operationNode.attributeValue(Constants.OPERATION_TYPE);
		OperationDescriptor descriptor = new OperationDescriptor(id,
				application, type);
		return descriptor;
	}

}
